如果外面的struct裡面是包struct,在宣告出來了時候,裡面的struct是定死的,變數就是指定要宣告時的struct型態。
如下所示
// Tool 工具
type Tool struct {
id int
name string
power float64
}
// Employee 員工
type Employee struct {
id int
age int
t Tool
}
var employee Employee
宣告出來的employee內的t變數,就是一個擁有zero value的Tool結構。
如果改天要調整Tool相關的需求,那可就很麻煩了。
上面簡單表示了兩種struct,Tool(員工)和Employee(工具),我們規劃上兩者有一定的關係,員工會使用工具之類的。
來舉個需求變更的例子。
後來出了新的Tool,不巧的外國的Tool設計的不一樣,只好設計新的結構Tool2。
// Tool2 工具2
type Tool2 struct {
id string
name string
power float64
weight float64
}
需求上,employee 要能夠選用Tool 或Tool2,不可以一開始就決定,或者限用當中某一種,該怎麼辦?
遇到這樣的狀況,有些人開始把腦筋動到Employee的結構上。
沒說員工不能夠一口氣使用兩種工具對吧?
雙刀流錯了嗎
type Employee struct {
id int
age int
t1 Tool
t2 Tool2
}
萬能的interface,真正使用的時候再來判斷手上拿的是哪一種工具。
type Employee struct {
id int
age int
t interface{}
}
復仇者聯盟都可以內戰,為什麼員工不能分兩派,拿不同的工具,就視為不同種員工吧。
type Employee1 struct {
id int
age int
t Tool
}
type Employee2 struct {
id int
age int
t2 Tool
}
員工不跟工具綁在一起,要用工具的話,呼叫method,要用哪種method?先有經過條件判斷,再選哪種method呀。
// UseTool1 使用工具1
func (e *Employee) UseTool1(t *Tool) {
// 員工使用工具
}
// UseTool2 使用工具2
func (e *Employee) UseTool2(t *Tool2) {
// 員工使用工具
}
這個情況就筆者經驗來說,尤其嚴重與常見,容易衍伸兩個麻煩問題。
多一種工具,就多一個method,然後選用method之前需要先經過判斷,所以容易跑出一大片的case switch在做這樣的處理。程式成長到一定規模,開始會眼花撩亂,並且維護上越趨困難。
這部分比較是個人觀點,筆者認為直白表示Employee(員工)與Tool(工具)的暗示不見了,就如上一篇舉例的souce code,裡面的DB struct裡面就明白告訴你有個Connector,雖然初見之下,不知道它們有什麼姦情,但你能知道DB就是擁有個Connector,兩者彼此應該有某種關係。